package Domain.UserClient;


import Business.FrameHandler;
import Domain.DataManager;
import java.util.Vector;


import objects.*;
import Domain.stompProtocol.StompFrame;

import GUI.Register;
import Logger.ClientLogger;
import com.thoughtworks.xstream.XStream;
import java.util.logging.Level;
import java.util.logging.Logger;

public class SocketListener {

	private XStream _xstream;
        private DataManager _dm;
        private ButtonsFunctions _bf;

	/**
	 * constructor
	 * @param _socket the socket of the server
	 * @param printer the print writer
	 */
	public SocketListener(ButtonsFunctions bf, DataManager dm)
	{
		this._xstream = new XStream();
		_xstream.alias("ForumFrame", ForumFrame.class);

                this._bf = bf;
                this._dm = dm;
        }

	/**
	 * process the message received from the server
	 * @param msg the message received
	 */

	public void processMessage(StompFrame sFrame)
	{                                            
                //System.out.println(sFrame);

		int sFrameType = sFrame.getMsgType();
		if (sFrameType == StompFrame.MSGREGISTERED)
                {
                        processRegistered();
                }
                if (sFrameType == StompFrame.MSGUNREGISTERED)
                {
                    ClientLogger.write(Level.INFO,"msg unregistered");
                    processUnregistered();
                }
		else if(sFrameType == StompFrame.MSGCONNECTED)
                {
			processConnected();
		}
 		else if(sFrameType == StompFrame.MSGERROR)
                {
			processError(sFrame.toString());
		}
                else if(sFrameType==StompFrame.MSGANSISAVAILABLE){
                        processAvailabilityCheck(sFrame.getData());
                }
		else if(sFrameType == StompFrame.MSGSEND)
		{
			try
			{
                            
				ForumFrame fFrame = (ForumFrame)(_xstream.fromXML(sFrame.getData()));	
				int type = fFrame.getType();

				if(type == ForumFrame.VECTORFRM)
					processVectorFrm(fFrame);
				else if(type == ForumFrame.TYPESECCESS)
					processSuccess(fFrame);			//need to check which messages return success
				else if(type == ForumFrame.TYPETHREAD)
					processThread(fFrame);
				else if(type == ForumFrame.VECTORTRD)
					processVectorTrd(fFrame);
				else if(type == ForumFrame.VECTORUSER)
					processVectorUser(fFrame);
				else if(type == ForumFrame.VECTORMSG)
					processVectorMsg(fFrame);
                                else if(type == ForumFrame.VECTORFRIENDS)
					processVectorFriends(fFrame);
                                else if(type == ForumFrame.TYPEDefaultUser | type == ForumFrame.TYPEManager)
                                        processUserType(fFrame);
                                else if(type == ForumFrame.TYPEFriendPublishMsg)
					processFriendPublishMsg(fFrame);
                                else if(type == ForumFrame.TYPEUserPublishMsg)
                                        processUserPublishedMessage(fFrame);
				else if(type < 0)
					processError(fFrame);
				else
					System.out.println(sFrame);
			}
			catch(Exception e)
			{
				System.out.println("MY EXCEPTION:");
				e.printStackTrace();
			}
		}
		else				//MGGERROR or error in the type of StompFrame
		{
                    ClientLogger.write(Level.WARNING,"Error in type of StompFrame, the message recieved was:\n" + sFrame);
		}
	}



	private void processError(ForumFrame fFrame) 
	{
                ClientLogger.write(Level.WARNING,"An Error of type " +fFrame.type + " have been recieved.");
                if (fFrame.type==-10)
                {
                    processError("Thread name mush be uniqe in forum, please change the name.");
                }
                if (fFrame.type==-11)
                {
                    processError("Message name mush be uniqe in thread, please change the name.");
                }
                if (fFrame.type==-12)
                {
                    processError("Forum name mush be uniqe, please change the name.");
                }
                if (fFrame.type==-7)
                {
                    processError("Unknown error!.");
                }
	}

	private void processVectorMsg(ForumFrame fFrame) 
	{
            //System.out.println("lalalallalililili");
		try
		{
		//System.out.println("\n\nBIBIB\n\n")	;
                    Vector<Message> messages = (Vector<Message>)fFrame.getData();
			this._dm.setVectorMessages(messages);
                       // for (int i = 1; i < messages.size() + 1; i++)
			//{
			//	System.out.println("Message " + i + ": "+ messages.elementAt(i-1));
			//}
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}

	private void processVectorUser(ForumFrame fFrame) 
	{
		try
		{
			Vector<User> users = (Vector<User>)fFrame.getData();
                        this._dm.setVectorOfUsers(users);
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}

	private void processVectorTrd(ForumFrame fFrame) 
	{
		try
		{
			Vector<Trd> trds = (Vector<Trd>)fFrame.getData();
                        this._dm.setVerctorThreads(trds);
//                     
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}

	private void processThread(ForumFrame fFrame) 
	{
             ClientLogger.write(Level.INFO,"a single thread has been recived");
	}

	private void processSuccess(ForumFrame fFrame) 
	{
                this._dm.setSuccessOrFailure(this._dm.SUCCESS);
	}

	private void processVectorFrm(ForumFrame fFrame)
	{
		try
		{
                        Vector<Frm> forums = (Vector<Frm>)fFrame.getData();
                        this._dm.setVectorForums(forums);
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}


    private void processRegistered() {
        this._dm.setSuccessOrFailure(this._dm.SUCCESS);
    }

    private void processUnregistered() {
       // System.out.println("&&&&&&&&&&&&&&&&&&&&&&&&&&");
        this._dm.setSuccessOrFailure(this._dm.SUCCESS);
    }

    private void processConnected()
    {
        this._dm.setSuccessOrFailure(this._dm.SUCCESS);
    }

    private void processError(String error)
    {
         ClientLogger.write(Level.INFO,"error: " + error);
        this._dm.setSuccessOrFailure(this._dm.FAILURE);
        FrameHandler.getFrameHandler().showErrorMessage(error);
    }

    private void processUserType(ForumFrame fFrame)
    {
        int type;
        if(fFrame.getType() == ForumFrame.TYPEDefaultUser)
            type = 0;
        else if (fFrame.getType() == ForumFrame.TYPEManager)
            type = 1;
        else
        {
            type = -1;
            FrameHandler.getFrameHandler().showErrorMessage("Some error accured with getting user type - user type is  -1");
            return;
        }
        this._dm.setTypeOfUser(type);
    }

    private void processAvailabilityCheck(String ans){
        if(ans.equals("yes"))
            Register.changeErrLable("Available");
        else// if(ans.equals("no"))
            Register.changeErrLable("Not Available");

    }

    private void processVectorFriends(ForumFrame fFrame) {
        	try
		{
			Vector<User> friends = (Vector<User>)fFrame.getData();
                        this._dm.setVerctorFriends(friends);
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
    }

    private void processFriendPublishMsg(ForumFrame fFrame) {
        String str = (String)fFrame.getData();
        char delimiter = ';';
        int index = str.indexOf(delimiter)+1;
        int indexend = str.indexOf(delimiter, index);
        if(indexend == -1)
                indexend = str.length();
        String user = str.substring(0, index-1);
        String forum = str.substring(index,indexend).trim();
        String thread = str.substring(indexend+1,str.lastIndexOf(delimiter));
        String postTitle = str.substring(str.lastIndexOf(delimiter)+1);
//        System.out.println(str);
//        System.out.println("User: " + user +  "Forum: "+forum+"Thread: "+thread);
        this._dm.addNotification ( "Your friend \""+user +  "\" added\\edited the post \""+postTitle+"\" in thread \"" +thread + "\", forum \""+forum+"\".");
//        FrameHandler.getFrameHandler().showInfoMessage("Your Friend \"" + user +  "\" Published a new post in Forum \""+forum+"\" in Thread \""+thread + "\"");
//       ButtonsFunctions.getButtonsFunctions().processGetThreads(this._dm.getCurrForum());
    }

    private void processUserPublishedMessage(ForumFrame fFrame) {
        String str = (String)fFrame.getData();
        char delimiter = ';';
        int index = str.indexOf(delimiter)+1;
        int indexend = str.indexOf(delimiter, index);
        if(indexend == -1)
                indexend = str.length();
        String user = str.substring(0, index-1);
        String forum = str.substring(index,indexend).trim();
        String thread = str.substring(indexend+1,str.lastIndexOf(delimiter));

         String currUser = ButtonsFunctions.getButtonsFunctions().getCurrUser();

        if(forum.equals(DataManager.getDataManager().getCurrForum()) && !user.equals(currUser))
        	this._dm.addNotification("A new message has been added\\edited in thread \"" +thread + "\", forum \""+forum+"\".");
//        FrameHandler.getFrameHandler().showInfoMessage(user +  "\" has Published a new post in Forum \""+forum+"\" in Thread \""+thread + "\"");
    }

}
